package com.bxl.chooser.oper.impl;

import com.bxl.chooser.bean.AppInfo;
import com.bxl.chooser.bean.ChooseMsg;
import com.bxl.chooser.bean.ChooseResponseMsg;
import com.bxl.chooser.context.ChooserContext;
import com.bxl.chooser.factory.ChooseMsgFactory;
import com.bxl.chooser.oper.IOperSv;
import com.bxl.netty.rpc.client.common.client.ClientInfo;
import com.bxl.netty.rpc.common.message.PackageMsg;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <>
 *
 * @author baixl
 * @date 2021/3/26
 */
public class HeartBeatOperService implements IOperSv<ChooseResponseMsg> {
    private Logger logger = LoggerFactory.getLogger(HeartBeatOperService.class);
    @Override
    public ChooseResponseMsg oper(PackageMsg<ChooseMsg> msg, ChooserContext context) {
        ChooseMsg chooseMsg = msg.getContent();
        AppInfo appInfo = context.getAppInfo();
        logger.info("curLogindex {}; commitLogindex {}",appInfo.getLogIndex(),appInfo.getCommitLogIndex());
        //任期比较 
        if (chooseMsg.getTerm() >= appInfo.getTerm()) {
            System.out.println(String.format("Leader is %s, term is %s", chooseMsg.getAppId(), chooseMsg.getTerm()));

            if (!context.getHasLeader()) {
                context.setHasLeader(true);
                context.setLeader(new ClientInfo("CHOOSE", chooseMsg.getLeaderIp(), chooseMsg.getPort(), context.getClientContext()));
            }
            if (chooseMsg.getTerm() > appInfo.getTerm()) {
                //已经不是最新的term，降级为follower
                if (appInfo.getState() == AppInfo.AppState.LEADER) {
                    context.degraded();
                }
                appInfo.setTerm(chooseMsg.getTerm());
                context.setLeader(new ClientInfo("CHOOSE", chooseMsg.getLeaderIp(), chooseMsg.getPort(), context.getClientContext()));
            }

            context.getSlidingWindow().register(context.getLeader());
            return ChooseMsgFactory.createChooseResponseMsg(chooseMsg.getTerm(), true, context.getAppInfo().getLogIndex());
        }
        System.out.println(String.format("refuse leader %s, term is %s no largest",chooseMsg.getAppId(),chooseMsg.getTerm()));
        return ChooseMsgFactory.createChooseResponseMsg(appInfo.getTerm(), false);
    }
}
